<template>
  <div class="app-container">
    <el-row :gutter="20">
      <splitpanes :horizontal="store.state.app.device === 'mobile'" class="default-theme">
        <!--部门数据-->
        <pane size="16">
          <el-col>
            <div class="head-container">
              <el-input
                v-model="deptName"
                placeholder="请输入归属公司名称"
                clearable
                size="small"
                prefix-icon="Search"
                style="margin-bottom: 20px"
              />
            </div>
            <div class="head-container tree-container">
              <el-tree
                :data="deptOptions"
                :props="defaultProps"
                :expand-on-click-node="false"
                :filter-node-method="filterNode"
                ref="treeRef"
                node-key="id"
                default-expand-all
                highlight-current
                @node-click="handleNodeClick"
              />
            </div>
          </el-col>
        </pane>
        <!--用户数据-->
        <pane size="84">
          <el-col>
            <el-form
              :model="queryParams"
              ref="queryFormRef"
              size="small"
              :inline="true"
              v-show="showSearch"
              label-width="90px"
            >
              <el-form-item label="登录账号名" prop="userName">
                <el-input
                  v-model="queryParams.userName"
                  placeholder="请输入登录账号名"
                  clearable
                  style="width: 240px"
                  @keyup.enter="handleQuery"
                />
              </el-form-item>
              <el-form-item label="手机号码" prop="phonenumber">
                <el-input
                  v-model="queryParams.phonenumber"
                  placeholder="请输入手机号码"
                  clearable
                  style="width: 240px"
                  @keyup.enter="handleQuery"
                />
              </el-form-item>
              <el-form-item label="状态" prop="status">
                <el-select
                  v-model="queryParams.status"
                  placeholder="用户状态"
                  clearable
                  style="width: 240px"
                >
                  <el-option
                    v-for="dict in dict?.type?.sys_normal_disable"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="创建时间">
                <el-date-picker
                  v-model="dateRange"
                  style="width: 240px"
                  value-format="yyyy-MM-dd"
                  type="daterange"
                  range-separator="-"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                ></el-date-picker>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="handleQuery">搜索</el-button>
                <el-button @click="resetQuery">重置</el-button>
              </el-form-item>
            </el-form>

            <el-row :gutter="10" class="mb8">
              <el-col :span="1.5">
                <el-button type="primary" @click="handleAdd" v-hasPermi="['system:user:add']"
                  >新增</el-button
                >
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="danger"
                  :disabled="multiple"
                  @click="handleDelete"
                  v-hasPermi="['system:user:remove']"
                  >删除</el-button
                >
              </el-col>
              <el-col :span="1.5">
                <el-button type="info" @click="handleImport" v-hasPermi="['system:user:import']"
                  >导入</el-button
                >
              </el-col>
              <el-col :span="1.5">
                <el-button type="warning" @click="handleExport" v-hasPermi="['system:user:export']"
                  >导出</el-button
                >
              </el-col>
            </el-row>

            <el-table
              ref="tableRef"
              v-loading="loading"
              :data="userList"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="50" align="center" />
              <el-table-column
                label="登录账户名"
                align="center"
                key="userName"
                prop="userName"
                v-if="columns[0].visible"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="用户昵称"
                align="center"
                key="nickName"
                prop="nickName"
                v-if="columns[1].visible"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="归属公司"
                align="center"
                key="deptName"
                prop="dept.deptName"
                v-if="columns[2].visible"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="手机号码"
                align="center"
                key="phonenumber"
                prop="phonenumber"
                v-if="columns[3].visible"
                width="120"
              />
              <el-table-column
                label="账户状态"
                align="center"
                key="status"
                v-if="columns[4].visible"
              >
                <template #default="scope">
                  <el-switch
                    v-model="scope.row.status"
                    active-value="0"
                    inactive-value="1"
                    @change="handleStatusChange(scope.row)"
                  ></el-switch>
                </template>
              </el-table-column>
              <el-table-column
                label="创建时间"
                align="center"
                prop="createTime"
                v-if="columns[5].visible"
                width="160"
              >
                <template #default="scope">
                  <span>{{ parseTime(scope.row.createTime) }}</span>
                </template>
              </el-table-column>
              <el-table-column label="绑定状态" v-if="columns[6].visible">
                <template #default="{ row }">
                  <el-tag v-if="row.bandType == '1'" type="success">已绑定</el-tag>
                  <el-tag v-else type="danger">未绑定</el-tag>
                </template>
              </el-table-column>
              <el-table-column
                label="小程序手机号"
                prop="bandMobile"
                v-if="columns[7].visible"
              ></el-table-column>
              <el-table-column label="小程序头像" v-if="columns[8].visible">
                <template #default="{ row }">
                  <el-image
                    v-if="row.bandAvatar != null && row.bandAvatar != ''"
                    style="width: 40px; height: 40px"
                    :src="row.bandAvatar"
                    fit="cover"
                  />
                </template>
              </el-table-column>
              <el-table-column label="已绑定场馆" v-if="columns[9].visible">
                <template #default="{ row }">
                  <el-button type="text" v-if="row.bandType == '1'" @click="handleExpand(row)"
                    >查看绑定</el-button
                  >
                </template>
              </el-table-column>
              <el-table-column type="expand" width="1">
                <template #default="{ row }">
                  <el-table :data="row.bandStadiums">
                    <el-table-column
                      prop="stadiumName"
                      label="场馆名"
                      :show-overflow-tooltip="true"
                    ></el-table-column>
                    <el-table-column
                      prop="createTime"
                      label="绑定时间"
                      :show-overflow-tooltip="true"
                    ></el-table-column>
                    <el-table-column label="操作" align="center">
                      <template #default="{ row }">
                        <el-button
                          type="text"
                          @click="cancelBand(row)"
                          v-hasPermi="['system:user:band']"
                          >解绑</el-button
                        >
                      </template>
                    </el-table-column>
                  </el-table>
                </template>
              </el-table-column>
              <el-table-column
                label="操作"
                align="center"
                width="180"
                class-name="small-padding fixed-width"
              >
                <template #default="scope">
                  <div v-if="scope.row.userId !== 1">
                    <el-button
                      type="text"
                      @click="handleBand(scope.row)"
                      v-hasPermi="['system:user:band']"
                      >绑定</el-button
                    >
                    <el-button
                      style="color: rgba(56, 56, 56, 1)"
                      type="text"
                      @click="handleUpdate(scope.row)"
                      v-hasPermi="['system:user:edit']"
                      >修改</el-button
                    >
                    <el-button
                      style="color: rgba(56, 56, 56, 1)"
                      type="text"
                      @click="handleDelete(scope.row)"
                      v-hasPermi="['system:user:remove']"
                      >删除</el-button
                    >
                    <el-dropdown
                      @command="(command) => handleCommand(command, scope.row)"
                      icon="ArrowRight"
                      v-hasPermi="['system:user:resetPwd', 'system:user:edit']"
                    >
                      <el-button style="color: rgba(56, 56, 56, 1)" type="text" icon="ArrowRight"
                        >更多</el-button
                      >
                      <template #default:dropdown>
                        <el-dropdown-menu>
                          <el-dropdown-item
                            command="handleResetPwd"
                            v-hasPermi="['system:user:resetPwd']"
                            >重置密码</el-dropdown-item
                          >
                          <el-dropdown-item
                            command="handleAuthRole"
                            v-hasPermi="['system:user:edit']"
                            >分配角色</el-dropdown-item
                          >
                        </el-dropdown-menu>
                      </template>
                    </el-dropdown>
                  </div>
                </template>
              </el-table-column>
            </el-table>

            <pagination
              v-show="total > 0"
              :total="total"
              v-model:page="queryParams.pageNum"
              v-model:limit="queryParams.pageSize"
              @pagination="getList"
            />
          </el-col>
        </pane>
      </splitpanes>
    </el-row>

    <!-- 添加或修改用户配置对话框 -->
    <el-dialog
      :title="title"
      v-model="open"
      width="600px"
      append-to-body
      :close-on-click-modal="false"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="归属公司" prop="deptId">
          <el-tree-select
            v-model="form.deptId"
            :data="enabledDeptOptions"
            :props="{ value: 'deptId', label: 'deptName', children: 'children' }"
            node-key="id"
            placeholder="请选择归属公司"
            check-strictly
            default-expand-all
            :render-after-expand="false"
          />
        </el-form-item>
        <el-form-item v-if="form.userId == undefined" label="登录账号名" prop="userName">
          <el-input v-model="form.userName" placeholder="请输入登录账号名" maxlength="30" />
        </el-form-item>
        <el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
          <el-input
            v-model="form.password"
            placeholder="请输入用户密码"
            type="password"
            maxlength="20"
            show-password
          />
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="用户昵称" prop="nickName">
              <el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="手机号码" prop="phonenumber">
              <el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-form-item label="角色" prop="roleIds">
            <el-select style="width: 100%" v-model="form.roleIds" multiple placeholder="请选择角色">
              <el-option
                v-for="item in roleOptions"
                :key="item.roleId"
                :label="item.roleName"
                :value="item.roleId"
                :disabled="item.status == 1"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 用户导入对话框 -->
    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
      <el-upload
        ref="uploadRef"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url + '?updateSupport=' + upload.updateSupport"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <template #default:tip>
          <div class="el-upload__tip text-center">
            <div class="el-upload__tip">
              <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
            </div>
            <span>仅允许导入xls、xlsx格式文件。</span>
            <el-link
              type="primary"
              :underline="false"
              style="font-size: 12px; vertical-align: baseline"
              @click="importTemplate"
              >下载模板</el-link
            >
          </div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button @click="upload.open = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <band-app-user
      v-show="bandAppUser"
      ref="bandAppUserDialogRef"
      @refreshShow="handleRefreshShow"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, watch, onMounted, getCurrentInstance } from 'vue'
import {
  listUser,
  getUser,
  delUser,
  addUser,
  updateUser,
  resetUserPwd,
  changeUserStatus,
  deptTreeSelect,
} from '@/api/system/user'
import { getConfigKey } from '@/api/system/config'
import { unbindUserV2 } from '@/api/system/appUser'
import { getToken } from '@/utils/auth'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import BandAppUser from '@/views/user/bandAppUser.vue'
import env from '@/utils/env'
import { ElMessageBox, type FormInstance } from 'element-plus'
import { parseTime, addDateRange } from '@/utils/cj'
import { useStore } from 'vuex'
import { useDict } from '@/utils/dict'

const { dict }: any = useDict({
  dicts: ['sys_normal_disable'],
})

// 获取当前实例
const { proxy } = getCurrentInstance() as any

const store = useStore()
// 遮罩层
const loading = ref(true)
// 选中数组
const ids = ref([])
// 非单个禁用
const single = ref(true)
// 非多个禁用
const multiple = ref(true)
// 显示搜索条件
const showSearch = ref(true)
// 总条数
const total = ref(0)
// 用户表格数据
const userList = ref([])
// 弹出层标题
const title = ref('')
// 所有部门树选项
const deptOptions = ref(undefined)
// 过滤掉已禁用部门树选项
const enabledDeptOptions = ref<any>(undefined)
// 是否显示弹出层
const open = ref(false)
// 部门名称
const deptName = ref(undefined)
// 默认密码
const initPassword = ref(undefined)
// 日期范围
const dateRange = ref([])
// 岗位选项
const postOptions = ref([])
// 角色选项
const roleOptions = ref<any[]>([])
const defaultProps = {
  children: 'children',
  label: 'label',
}
// 用户导入参数
const upload = reactive({
  // 是否显示弹出层（用户导入）
  open: false,
  // 弹出层标题（用户导入）
  title: '',
  // 是否禁用上传
  isUploading: false,
  // 是否更新已经存在的用户数据
  updateSupport: 0,
  // 设置上传的请求头部
  headers: { Authorization: 'Bearer ' + getToken() },
  // 上传的地址
  url: env.VITE_APP_BASE_API + '/system/user/importData',
})
// 查询参数
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  userName: undefined,
  phonenumber: undefined,
  status: undefined,
  deptId: undefined,
})
// 列信息
const columns = ref<any>([
  { key: 0, label: `登录账户名`, visible: true },
  { key: 1, label: `用户昵称`, visible: true },
  { key: 2, label: `归属公司`, visible: true },
  { key: 3, label: `手机号码`, visible: true },
  { key: 4, label: `账户状态`, visible: true },
  { key: 5, label: `创建时间`, visible: true },
  { key: 6, label: `绑定状态`, visible: true },
  { key: 7, label: `小程序手机号`, visible: true },
  { key: 8, label: `小程序头像`, visible: true },
  { key: 9, label: `已绑定场馆`, visible: true },
])
// 表单参数
const form = reactive<Record<string, any>>({
  userId: undefined,
  deptId: undefined,
  userName: undefined,
  nickName: undefined,
  password: undefined,
  phonenumber: undefined,
  email: undefined,
  sex: undefined,
  status: '0',
  remark: undefined,
  postIds: [],
  roleIds: [],
})
// 表单校验
const rules: any = {
  userName: [
    { required: true, message: '登录账号名称不能为空', trigger: 'blur' },
    { min: 2, max: 20, message: '登录账号名称长度必须介于 2 和 20 之间', trigger: 'blur' },
  ],
  nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
  sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
  deptId: [{ required: true, message: '归属公司不能为空', trigger: 'blur' }],
  roleIds: [{ required: true, message: '角色不能为空', trigger: 'blur' }],
  password: [
    { required: true, message: '用户密码不能为空', trigger: 'blur' },
    { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' },
    { pattern: /^[^<>"'|\\]+$/, message: '不能包含非法字符：< > " \' \\\ |', trigger: 'blur' },
  ],
  email: [
    {
      type: 'email',
      message: '请输入正确的邮箱地址',
      trigger: ['blur', 'change'],
    },
  ],
  phonenumber: [
    { required: true, message: '手机号码不能为空', trigger: 'blur' },
    {
      pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
      message: '请输入正确的手机号码',
      trigger: 'blur',
    },
  ],
}
const bandAppUser = ref(false)

// Refs
const queryFormRef = ref<FormInstance>()
const formRef = ref<FormInstance>()
const uploadRef = ref()
const treeRef = ref()
const tableRef = ref()
const bandAppUserDialogRef = ref()

// 根据名称筛选部门树
watch(deptName, (val) => {
  treeRef.value?.filter(val)
})

/** 查询用户列表 */
const getList = () => {
  loading.value = true
  listUser(addDateRange(queryParams, dateRange.value)).then((response: any) => {
    userList.value = response.rows
    total.value = response.total
    loading.value = false
  })
}

/** 查询部门下拉树结构 */
const getDeptTree = () => {
  deptTreeSelect().then((response: any) => {
    deptOptions.value = response.data
    enabledDeptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
  })
}

// 过滤禁用的部门
const filterDisabledDept = (deptList: any[]) => {
  return deptList.filter((dept) => {
    if (dept.disabled) {
      return false
    }
    if (dept.children && dept.children.length) {
      dept.children = filterDisabledDept(dept.children)
    }
    return true
  })
}

// 筛选节点
const filterNode = (value: any, data: any) => {
  if (!value) return true
  return data.label.indexOf(value) !== -1
}

// 节点单击事件
const handleNodeClick = (data: any) => {
  queryParams.deptId = data.id
  handleQuery()
}

// 用户状态修改
const handleStatusChange = (row: any) => {
  const text = row.status === '0' ? '启用' : '停用'
  proxy?.$modal
    .confirm('确认要"' + text + '""' + row.userName + '"用户吗？')
    .then(() => {
      return changeUserStatus(row.userId, row.status)
    })
    .then(() => {
      proxy?.$modal.msgSuccess(text + '成功')
    })
    .catch(() => {
      row.status = row.status === '0' ? '1' : '0'
    })
}

// 取消按钮
const cancel = () => {
  open.value = false
  reset()
}

// 表单重置
const reset = () => {
  Object.assign(form, {
    userId: undefined,
    deptId: undefined,
    userName: undefined,
    nickName: undefined,
    password: undefined,
    phonenumber: undefined,
    email: undefined,
    sex: undefined,
    status: '0',
    remark: undefined,
    postIds: [],
    roleIds: [],
  })
  formRef.value?.resetFields()
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNum = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  dateRange.value = []
  queryFormRef.value?.resetFields()
  queryParams.deptId = undefined
  treeRef.value?.setCurrentKey(null)
  handleQuery()
}

// 多选框选中数据
const handleSelectionChange = (selection: any) => {
  ids.value = selection.map((item: any) => item.userId)
  single.value = selection.length != 1
  multiple.value = !selection.length
}

// 更多操作触发
const handleCommand = (command: string, row: any) => {
  switch (command) {
    case 'handleResetPwd':
      handleResetPwd(row)
      break
    case 'handleAuthRole':
      handleAuthRole(row)
      break
    default:
      break
  }
}

/** 新增按钮操作 */
const handleAdd = () => {
  reset()
  getUser().then((response: any) => {
    postOptions.value = response.posts
    roleOptions.value = response.roles
    open.value = true
    title.value = '添加用户'
    form.password = initPassword.value
  })
}

/** 修改按钮操作 */
const handleUpdate = (row: any) => {
  reset()
  const userId = row.userId || ids.value
  getUser(userId).then((response: any) => {
    Object.assign(form, response.data)
    postOptions.value = response.posts
    roleOptions.value = response.roles
    form.postIds = response.postIds
    form.roleIds = response.roleIds
    open.value = true
    title.value = '修改用户'
    form.password = ''
  })
}

/** 重置密码按钮操作 */
const handleResetPwd = (row: any) => {
  ElMessageBox.prompt('请输入"' + row.userName + '"的新密码', {
    title: '提示',
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    closeOnClickModal: false,
    inputPattern: /^.{5,20}$/,
    inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
    inputValidator: (value: string) => {
      if (/<|>|"|'|\||\\/.test(value)) {
        return '不能包含非法字符：< > " \' \\\ |'
      }
      return false
    },
  })
    .then(({ value }) => {
      resetUserPwd(row.userId, value).then((response: any) => {
        proxy?.$modal.msgSuccess('修改成功，新密码是：' + value)
      })
    })
    .catch(() => {})
}

/** 分配角色操作 */
const handleAuthRole = (row: any) => {
  const userId = row.userId
  proxy?.$router.push('/system/user-auth/role/' + userId)
}

/** 提交按钮 */
const submitForm = () => {
  if (!formRef.value) return
  formRef.value.validate((valid: boolean) => {
    if (valid) {
      if (form.userId != undefined) {
        updateUser(form).then((response: any) => {
          proxy?.$modal.msgSuccess('修改成功')
          open.value = false
          getList()
        })
      } else {
        addUser(form).then((response: any) => {
          proxy?.$modal.msgSuccess('新增成功')
          open.value = false
          getList()
        })
      }
    }
  })
}

/** 删除按钮操作 */
const handleDelete = (row: any) => {
  const userIds = row.userId || ids.value
  proxy?.$modal
    .confirm('是否确认删除用户编号为"' + userIds + '"的数据项？')
    .then(() => {
      return delUser(userIds)
    })
    .then(() => {
      getList()
      proxy?.$modal.msgSuccess('删除成功')
    })
    .catch(() => {})
}

/** 导出按钮操作 */
const handleExport = () => {
  proxy?.download(
    'system/user/export',
    {
      ...queryParams,
    },
    `user_${new Date().getTime()}.xlsx`,
  )
}

/** 导入按钮操作 */
const handleImport = () => {
  upload.title = '用户导入'
  upload.open = true
}

/** 下载模板操作 */
const importTemplate = () => {
  proxy?.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`)
}

// 文件上传中处理
const handleFileUploadProgress = (event: any, file: any, fileList: any) => {
  upload.isUploading = true
}

// 文件上传成功处理
const handleFileSuccess = (response: any, file: any, fileList: any) => {
  upload.open = false
  upload.isUploading = false
  uploadRef.value?.clearFiles()
  proxy?.$alert(
    "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
      response.msg +
      '</div>',
    '导入结果',
    { dangerouslyUseHTMLString: true },
  )
  getList()
}

// 提交上传文件
const submitFileForm = () => {
  uploadRef.value?.submit()
}

// 查看绑定详情
const handleExpand = (row: any) => {
  const $table = tableRef.value
  userList.value.map((item: any) => {
    if (row.userId != item.userId) {
      $table.toggleRowExpansion(item, false)
    }
  })
  $table.toggleRowExpansion(row)
}

// 绑定
const handleBand = (data: any) => {
  bandAppUser.value = true
  bandAppUserDialogRef.value?.init(data)
}

// 刷新
const handleRefreshShow = () => {
  bandAppUser.value = false
  getList()
}

// 解除绑定
const cancelBand = (item: any) => {
  proxy?.$confirm('确认解除绑定吗？').then(() => {
    loading.value = true
    unbindUserV2(item)
      .then((res: any) => {
        loading.value = false
        proxy?.$message.success('解除绑定成功')
        getList()
      })
      .catch((e: any) => {
        loading.value = false
      })
  })
}

onMounted(() => {
  getList()
  getDeptTree()
  getConfigKey('sys.user.initPassword').then((response: any) => {
    initPassword.value = response.msg
  })
})
</script>

<style lang="scss" scoped>
.tree-container {
  max-height: 80vh;
  overflow: auto;
}
</style>
